using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace iPhOwa.Exchange
{
	/// <summary>
	/// Extends the dictionary for easily converting objects.
	/// </summary>
	[Serializable]
	public class PropertyDictionary : Dictionary<string, string>
	{
		/// <summary>
		/// Constructor.
		/// </summary>
		public PropertyDictionary() {}

		/// <summary>
		/// Constructor.
		/// </summary>
		protected PropertyDictionary(SerializationInfo info, StreamingContext context) : base(info, context) {}

		///<summary>
		/// Gets or sets the element with the specified key, if get and the key doesn't exit, null is returned.
		///</summary>
		public new string this[string key]
		{
			get
			{
				string result;

				TryGetValue(key, out result);

				return result;
			}
			set { base[key] = value; }
		}

		/// <summary>
		/// Try to get an <see cref="Uri"/> from the dictionary.
		/// </summary>
		public Uri GetUri(string key)
		{
			Uri result = null;

			string propertyValue = this[key];

			if(!string.IsNullOrEmpty(propertyValue))
			{
				Uri.TryCreate(propertyValue, UriKind.RelativeOrAbsolute, out result);
			}

			return result;
		}

		/// <summary>
		/// Try to get an <see cref="Boolean"/> from the dictionary.
		/// </summary>
		public Boolean GetBoolean(string key)
		{
			Boolean result;

			bool success = Boolean.TryParse(this[key], out result);

			// might be 1 or 0
			if(!success)
			{
				result = Convert.ToBoolean(GetInt32(key));
			}

			return result;
		}

		/// <summary>
		/// Try to get an <see cref="Int64"/> from the dictionary.
		/// </summary>
		[SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Int64.TryParse(System.String,System.Int64@)")]
		public Int64 GetInt64(string key)
		{
			Int64 result;

			Int64.TryParse(this[key], out result);

			return result;
		}

		/// <summary>
		/// Try to get an <see cref="Int32"/> from the dictionary.
		/// </summary>
		[SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Int32.TryParse(System.String,System.Int32@)")]
		public Int32 GetInt32(string key)
		{
			Int32 result;

			Int32.TryParse(this[key], out result);

			return result;
		}

		/// <summary>
		/// Try to get an <see cref="DateTime"/> from the dictionary.
		/// </summary>
		[SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.DateTime.TryParse(System.String,System.DateTime@)")]
		public DateTime GetDateTime(string key)
		{
			DateTime result;

			DateTime.TryParse(this[key], out result);

			return result;
		}

		/// <summary>
		/// Attempt to parse an enum value.
		/// </summary>
		[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
		public T GetEnum<T>(string key)
		{
			try
			{
				return (T)Enum.Parse(typeof(T), this[key], true);
			}
			catch(ArgumentNullException)
			{
				return default(T);
			}
			catch(ArgumentException)
			{
				return default(T);
			}
		}
	}
}